﻿using System;
using System.Web;
using Pay.DTO;
using Pay.Core;
using System.Threading.Tasks;
using Flurl.Http;
using System.Net.Http;
using System.Collections.Generic;

namespace Pay.Service {
	public class SxyPaySign {
		public SxyPaySign() {
		}
#if DEBUG
		private string sxy_pay_secret_url = "~/cer/cfca_private_17759.pfx";
		private string sxy_pay_pub_url = "~/cer/payease_cfca.cer";
		public string sxy_api_url = "https://paytest.yizhifubj.com/customer/gb/pay_bank.jsp";
		private string sxy_api_query_url = "https://paytest.yizhifubj.com";
		private string sxy_customs_api_url = "http://customs.yizhifubj.com";
		public string Partner = "17759";
		private string Key = "test";
		private string pfxPassword = "lh121121";
#else
		private string sxy_pay_secret_url = "~/cer/cfca_private_17759.pfx";
		private string sxy_pay_pub_url = "~/cer/payease_cfca.cer";
		public string sxy_api_url = "https://pay.yizhifubj.com/customer/gb/pay_bank.jsp";
		private string sxy_api_query_url = "https://api.yizhifubj.com";
		private string sxy_customs_api_url = "http://customs.yizhifubj.com";
		public string Partner = "17759";
		private string Key = "test";
		private string pfxPassword = "lh121121";
#endif
		/// <summary>
		/// 易支付查询接口
		/// </summary>
		/// <returns>The gateway.</returns>
		/// <param name="model">Model.</param>
		/// <param name="url">URL.</param>
		/// <typeparam name="T">The 1st type parameter.</typeparam>
		public async Task<T> PayGateway<T>(sxy_gateway_query model, string url) where T : sxy_result_base, new() {
			var log = IocHelper.Get<ILogHelper>("info");
			try {
				string privatepfxpath = HttpContext.Current.Server.MapPath(sxy_pay_secret_url);
				string data = model.v_mid + model.v_oid;
				model.v_mac = MerchantX509Cert.Sign(data, privatepfxpath, pfxPassword);
				var content = _sign(model);
				var formUrlContent = new FormUrlEncodedContent(content);
				var result = await (sxy_api_query_url + url).PostAsync(formUrlContent).ReceiveString();
				log.Info(result);
				return result.ToObject<T>();
			} catch (FlurlHttpException ex) {
				log.Error(ex.Message);
				return default(T);
			}
		}
		/// <summary>
		/// 海关推送接口
		/// </summary>
		/// <returns>The gateway.</returns>
		/// <param name="model">Model.</param>
		/// <param name="url">URL.</param>
		/// <typeparam name="T">The 1st type parameter.</typeparam>
		public async Task<T> PayGateway<T>(sxy_customs_push_req model, string url) where T : sxy_customs_result_base, new() {
			var log = IocHelper.Get<ILogHelper>("info");
			try {
				var content = _sign(model);
				var formUrlContent = new FormUrlEncodedContent(content);
				var resultApi = await (sxy_customs_api_url + url).PostAsync(formUrlContent).Result.Content.ReadAsStringAsync();
				var message = JsonHelper.XmlDeserialize(resultApi, System.Text.Encoding.UTF8);
				var result = new T();
				result.Status = message.Head.Status;
				result.StatusDesc = message.Head.StatusDesc;
				result.retCode = message.Response.retCode;
				result.retMsg = message.Response.retMsg;
				return result;
			} catch (FlurlHttpException ex) {
				log.Error(ex.Message);
				return default(T);
			}
		}

		private Dictionary<string, string> _sign(object model) {
			var content = new Dictionary<string, string>();
			string json = model.ToJson();
			var collection = json.ToObject<Dictionary<string, object>>();
			foreach (var kv in collection) {
				if (kv.Value != null && !string.IsNullOrEmpty(kv.Value.ToString())) {
					content.Add(kv.Key, kv.Value.ToString());
				}
			}
			return content;
		}
		/// <summary>
		/// 签名
		/// </summary>
		/// <returns>The sign.</returns>
		/// <param name="model">Model.</param>
		public string Sign(sxy_gateway_pay model) {
			//pfx私钥
			string privatepfxpath = HttpContext.Current.Server.MapPath(sxy_pay_secret_url);
			string data = model.v_moneytype + model.v_ymd + model.v_amount + model.v_rcvname + model.v_oid + model.v_mid + model.v_url;
			string v_md5info = MerchantX509Cert.Sign(data, privatepfxpath, pfxPassword);
			return v_md5info;
		}
		/// <summary>
		/// 同步验签
		/// </summary>
		/// <returns><c>true</c>, if sign was verifyed, <c>false</c> otherwise.</returns>
		/// <param name="model">Model.</param>
		public bool VerifySign(sxy_gateway_result model) {
			bool result = false;
			ClassHmac mac = new ClassHmac();
			model.v_pstring = System.Web.HttpUtility.UrlEncode(model.v_pstring, System.Text.Encoding.UTF8).ToUpper();
			model.v_pmode = System.Web.HttpUtility.UrlEncode(model.v_pmode, System.Text.Encoding.UTF8).ToUpper();
			//数字指纹验签md5info
			string info = model.v_oid + model.v_pstatus + model.v_pstring + model.v_pmode;
			string md5info = mac.hex_hmac_md5(info, Key);
			//数字指纹验签md5money
			string money = model.v_amount + model.v_moneytype;
			string md5money = mac.hex_hmac_md5(money, Key);
			//cer公钥
			string publiccrepath = HttpContext.Current.Server.MapPath(sxy_pay_pub_url);
			//需要验签字符串
			string strsign = model.v_oid + model.v_pstatus + model.v_amount + model.v_moneytype;
			//公钥验签，两种都可以通用
			bool rebo = MerchantX509Cert.VerifySign(strsign, publiccrepath, model.v_sign);
			if (model.v_md5info == md5info && model.v_md5money == md5money && rebo) {
				result = true;
			}
			return result;
		}
		/// <summary>
		/// 异步验签
		/// </summary>
		/// <returns><c>true</c>, if verify sign was asyced, <c>false</c> otherwise.</returns>
		/// <param name="model">Model.</param>
		public bool AsycVerifySign(sxy_asyc_result model) {
			//cer公钥
			string publiccrepath = HttpContext.Current.Server.MapPath(sxy_pay_pub_url);
			string strsign = model.v_oid + model.v_pstatus + model.v_amount + model.v_moneytype + model.v_count;
			bool result = MerchantX509Cert.VerifySign(strsign, publiccrepath, model.v_sign);
			return result;
		}
	}
}
